Skip to content

Conversation

@junaruga
Copy link
Member

This PR is working in progress.

I see the test failures on LibreSSL and AWS-LC cases.


  • Use the AES-256-CBC using PBKDF2 which is FIPS-approved, instead of the PBE-SHA1-3DES using PKCS12KDF which is not FIPS-approved. See also the man page openssl-pkcs12(1).
  • OpenSSL::PKCS12.create calling the PKCS12_create has the argument mac_iter which uses a MAC key using PKCS12KDF which is not FIPS-approved. In the FIPS case, set the mac_iter = -1 to omit the MAC key. See also the man page PKCS12_create(3).
  • As the test data OpenSSL::PKCS12.new calling PKCS12_parse verifies the MAC using PKCS12KDF which is not FIPS-approved, I created the test data without MAC by the openssl pkcs12 -nomac.

@rhenium
Copy link
Member

rhenium commented Jan 21, 2026

I feel these existing tests should simply be skipped. My impression is that PKCS#12 is currently effectively unsupported in FIPS environments as I doubt password-based PKCS#12 is actually used without a MAC.

I think PKCS12_create() allows omitting the MAC mainly so that users can set a MAC with non-default parameters later, for example as shown in #772.

On a side note, RFC 9579 / RFC 9879 introduced an alternative MAC algorithm based on PBMAC1 from PKCS#5v2, which I think is FIPS-compatible. However, this is still pretty new and we don't have a wrapper for it yet: https://docs.openssl.org/master/man3/PKCS12_gen_mac/

* Use the `AES-256-CBC` using `PBKDF2` which is FIPS-approved, instead of the
  `PBE-SHA1-3DES` using `PKCS12KDF` which is not FIPS-approved. As the
  `AES-256-CBC` is also used as `openssl pkcs12`'s default algorithm, the case
   is typical. See also the man page openssl-pkcs12(1).
* `OpenSSL::PKCS12.create` calling the `PKCS12_create` uses a MAC key using
  `PKCS12KDF` which is not FIPS-approved.
* The test data `OpenSSL::PKCS12.new` calling `PKCS12_parse` verifies the MAC
  using `PKCS12KDF` which is not FIPS-approved.
@junaruga junaruga force-pushed the wip/fips-test-pkcs12 branch from 24b8de6 to 4c7ffa6 Compare January 21, 2026 19:13
@junaruga
Copy link
Member Author

junaruga commented Jan 21, 2026

I feel these existing tests should simply be skipped. My impression is that PKCS#12 is currently effectively unsupported in FIPS environments as I doubt password-based PKCS#12 is actually used without a MAC.

Okay. That makes sense. I think we want to test popular use cases.

I rebased the PR without MAC less key.

I am still using the AES-256-CBC as much as possible. Because I feel the AES-256-CBC is more modern and more typical. The AES-256-CBC is also used as openssl pkcs12's default algorithm according to the man page openssl-pkcs12(1).

However, LibreSSL's OpenSSL::PKCS12.create didn't accept the pass: nil in the case of the AES-256-CBC in the test_create_no_pass. The folllowing LibreSSL man page PKCS12_newpass shows a hint not not to accept the NULL.

https://man.openbsd.org/PKCS12_newpass.3

If the PKCS#12 structure does not have a password, use the empty string "" for oldpass. Passing NULL for oldpass results in a PKCS12_newpass() failure.

And AWS-LC's OpenSSL::PKCS12.create raised "UNKNOWN_ALGORITHM" in AWS-LC with AES-256-CBC. So, I added some conditional logic.

If you don't like this conditional logic, I can change this PR's source code back to use the PBE-SHA1-3DES as value of the DEFAULT_PBE_PKEYS and DEFAULT_PBE_CERTS used in the master branch.

What do you think?

@junaruga junaruga marked this pull request as ready for review January 21, 2026 19:26
# OpenSSL::PKCS12.create calling the PKCS12_create() has the argument
# mac_iter which uses a MAC key using PKCS12KDF which is not
# FIPS-approved.
omit_on_fips
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just do return if OpenSSL.fips_mode at the top of this file since we skip all of them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I didn't notice I skipped all of the tests in the test_pkcs12.rb on this PR. Yes, just skipping all the tests at the top of this file is much better. Let me fix it.

# algorithm, the case is typical. See also the man page openssl-pkcs12(1).
# OpenSSL::PKCS12.create raises UNKNOWN_ALGORITHM in AWS-LC with AES-256-CBC.
DEFAULT_PBE_PKEYS = aws_lc? ? "PBE-SHA1-3DES" : "AES-256-CBC"
DEFAULT_PBE_CERTS = aws_lc? ? "PBE-SHA1-3DES" : "AES-256-CBC"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be precise, PBE-SHA1-3DES uses PBKDF1 in PKCS#5 rather than PKCS12KDF. PKCS12KDF is only used for the outer MAC. I'd drop the FIPS reference because it's not relevant.

I noticed you updated the base64-encoded examples to use PBES2, and these tests are passing even with AWS-LC. Did we run into an incompatibility in PKCS12_create()? If so, it might be better to just skip these tests.

@rhenium
Copy link
Member

rhenium commented Jan 23, 2026

However, LibreSSL's OpenSSL::PKCS12.create didn't accept the pass: nil in the case of the AES-256-CBC in the test_create_no_pass. The folllowing LibreSSL man page PKCS12_newpass shows a hint not not to accept the NULL.

https://man.openbsd.org/PKCS12_newpass.3

This is interesting. It appears that the underlying function in OpenSSL, EVP_PBE_CipherInit_ex() accepts NULL to mean an empty password, as an undocumented behavior. It doesn't make sense to me, but I think it might be just for historical reason.

I also think using PBES2/AES is better, but I'd prefer to reduce conditionals because I'm not very familiar with PKCS#12 and want to keep it simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants